package org.flexharmony.eclipse;

import static org.flexharmony.eclipse.utils.CommonMethods.*;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ILightweightLabelDecorator;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.swt.widgets.Display;
import org.flexharmony.eclipse.nature.HarmonyProjectNature;
import org.flexharmony.eclipse.properties.PropertiesConstants;

public class HarmonyDecorator implements ILightweightLabelDecorator
{
  static private HarmonyDecorator singleton;
  
  static public void notifyConfigChange()
  {
    if (singleton == null) return;

    // Decorate using current UI thread
    Display.getDefault().asyncExec(new Runnable()
    {
      public void run()
      { 
        LabelProviderChangedEvent event = new LabelProviderChangedEvent(singleton);
        for (ILabelProviderListener listener : singleton.listeners)
        {
          listener.labelProviderChanged(event);
        }
      }
    });
  }
  static public final ImageDescriptor JAVA_OVERLAY = HarmonyPlugin.getImageDescriptor("icons/javaArrow.gif");

  static public final ImageDescriptor ACTIONSCRIPT_OVERLAY = HarmonyPlugin.getImageDescriptor("icons/actionScriptArrow.gif");

  private List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>();
  
  public HarmonyDecorator()
  {
    singleton = this;
  }

  public void decorate(Object element, IDecoration decoration)
  {
    IFile file = (IFile)element;
    IProject project = file.getProject();

    try
    {
      if (project.getNature(HarmonyProjectNature.NATURE_ID) == null) return;
      
      String fileName = file.getName();
      IPath filePath = file.getFullPath();
      if (fileName.endsWith(".java"))
      {
        IJavaProject javaProject = JavaCore.create(project);
        IClasspathEntry[] classPathEntries = javaProject.getRawClasspath();
        if (classPathEntries != null)
        {
          for (IClasspathEntry classPathEntry : classPathEntries)
          {
            if (classPathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE)
            {
              IPath sourcePath = classPathEntry.getPath();
              if (sourcePath.isPrefixOf(filePath))
              {
                if (matchesPatterns(project, sourcePath, filePath))
                {
                  decoration.addOverlay(JAVA_OVERLAY, 0);
                }
                break;
              }
            }
          }
        }
      }
      else if (fileName.endsWith(".as"))
      {
        String flexSrcDirName = project.getPersistentProperty(PropertiesConstants.FLEX_SRC_DIR_NAME_QNAME);
        if (flexSrcDirName == null) return;
        
        IFolder flexSrcDir = project.getFolder(flexSrcDirName);
        
        if (!flexSrcDir.exists()) return;
        
        IPath flexSrcDirPath = flexSrcDir.getFullPath();
        
        if (!flexSrcDirPath.isPrefixOf(filePath)) return;
        
        String relativeAsFilePathName = filePath.removeFirstSegments(flexSrcDirPath.segmentCount()).toString();
        String relativeJavaFilePathName = relativeAsFilePathName.substring(0, (relativeAsFilePathName.length() - 3)) + ".java";
        IPath relativeJavaFilePath = new Path(relativeJavaFilePathName);
        IPath javaSourceRoot = findJavaSourceRoot(project, relativeJavaFilePath);
        if (javaSourceRoot != null)
        {
          IPath fullJavaFilePath = javaSourceRoot.append(relativeJavaFilePath);
          if (matchesPatterns(project, javaSourceRoot, fullJavaFilePath))
          {
            decoration.addOverlay(ACTIONSCRIPT_OVERLAY, 2);
          }
        }
      }

    }
    catch (CoreException cexc)
    {
      cexc.printStackTrace();
    }
  }

  public void addListener(ILabelProviderListener listener)
  {
    if (!listeners.contains(listener)) listeners.add(listener);
  }

  public void removeListener(ILabelProviderListener listener)
  {
    listeners.remove(listener);
  }

  public void dispose()
  {
    // TODO Auto-generated method stub

  }

  public boolean isLabelProperty(Object element, String property)
  {
    // TODO Auto-generated method stub
    return false;
  }
}
